package com.zznzzn.myweb.service;

import com.zznzzn.myweb.Properties.MyProperties;
import com.zznzzn.myweb.exceptions.ServiceException;
import com.zznzzn.myweb.mapper.FileMapper;
import com.zznzzn.myweb.mapper.UserMapper;
import com.zznzzn.myweb.util.Base64Util;
import com.zznzzn.myweb.util.FileNameUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.List;


@Service
public class FileServiceImpl implements FileService {


    @Autowired
    private MyProperties properties;

    //    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private FileMapper fileMapper;

    @Override
    public String receiveAvatar(MultipartFile file, int size) {
        return processPic(file, size, true);
    }

    @Override
    public String receivePic(MultipartFile file, int size) {
        return processPic(file, size, false);
    }

    @Override
    public int setAvatar(String uuid, String filepath, String color) {
        return userMapper.updateUserAvatar(filepath, color, uuid);
    }

    /**
     * @param file
     * @return filename on /upload
     */
    public String processPic(MultipartFile file, int size, boolean isAvatar) {
        try {
            String picType = FileNameUtil.getFileExtension(file.getOriginalFilename());
            //强迫症
            if (picType.equals("jpeg")) {
                picType = "jpg";
            }
            String filename = Base64Util.newUUID().substring(0, 21);
            BufferedInputStream bis = new BufferedInputStream(file.getInputStream());
            BufferedImage image = ImageIO.read(bis);
            BufferedImage target;

            //clip and scale
            int height = image.getHeight();
            int width = image.getWidth();
            int min = Math.min(height, width);
            //clip the image
            BufferedImage subimage = image.getSubimage(
                    (width - min) / 2,
                    (height - min) / 2,
                    min,
                    min
            );
            //scale to small
            if (min > size) {
                Image scaledInstance = subimage.getScaledInstance(size, size, Image.SCALE_SMOOTH);
                target = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);
                target.getGraphics().drawImage(scaledInstance, 0, 0, size, size, null);
            } else {
                target = new BufferedImage(min, min, BufferedImage.TYPE_INT_RGB);
                target.getGraphics().drawImage(subimage, 0, 0, min, min, null);
            }

            // the exception will throw to top
            savePic(target, filename, picType, isAvatar);

            return filename + "." + picType;
        } catch (IOException e) {
            throw new ServiceException(e.getMessage());
        }

    }

    public void savePic(BufferedImage image, String filename, String picType, boolean isAvatar) throws IOException {
        File target;
        // create dirs if not exists
        File avatar = new File(properties.getUpload_file_path() + File.separator + properties.getAvatar_dir());
        if (!avatar.exists()) {
            avatar.mkdirs();
        }

        //start save
        if (isAvatar) {
            target = new File(
                    properties.getUpload_file_path() + File.separator + properties.getAvatar_dir()
                            + File.separator + filename + "." + picType);

        } else {
            target = new File(properties.getUpload_file_path() + File.separator + filename + "." + picType);
        }
//        System.out.println(target.getAbsolutePath());
        BufferedOutputStream bos;
        try {
            bos = new BufferedOutputStream(new FileOutputStream(target));

            ImageIO.write(image, picType, bos);
//            System.out.println("save success");

            bos.close();
        } catch (FileNotFoundException e) {
            throw new ServiceException("创建文件失败");
        }
    }

    @Override
    public void deleteLocalFile(String path, boolean isAvatar) {
        if (isAvatar) {
            File file1 = new File(properties.getUpload_file_path() + File.separator + properties.getAvatar_dir()
                    + File.separator + path);
            System.out.println(file1.getAbsolutePath());
            if (file1.exists()) {
                file1.delete();
            } else {
                throw new ServiceException("文件不存在");
            }
        } else {
            File file = new File(properties.getUpload_file_path() + File.separator + path);
            if (file.exists()) {
                file.delete();
            } else {
                throw new ServiceException("文件不存在");
            }
        }
    }

    @Override
    public List<String> receivePictures(MultipartFile[] files, String watermask) {
        List<String> filenames = new ArrayList<>();
        for (MultipartFile file : files) {
            filenames.add(processPicWithNick(file, watermask));
        }
        return filenames;
    }

    public String processPicWithNick(MultipartFile file, String watermask) {
        try {
            String picType = FileNameUtil.getFileExtension(file.getOriginalFilename());
            //强迫症
            if (picType.equals("jpeg")) {
                picType = "jpg";
            }
            String filename = Base64Util.newUUID().substring(0, 21);
            BufferedInputStream bis = new BufferedInputStream(file.getInputStream());
            BufferedImage image = ImageIO.read(bis);
            BufferedImage target;

            int height = image.getHeight();
            int width = image.getWidth();
            int max = Math.max(height,width);
            int targett = Math.max(height,width);
            int clip = 1;

            // if image is too big ,clip to under 1000px
            while(targett>1000){
                targett /= 2;
            }
            clip = max/targett;



            Font font = new Font("微软雅黑", Font.PLAIN, (width / 20) /clip);
            Color color = new Color(255, 255, 255, 200);

            target = new BufferedImage(width/clip, height/clip, BufferedImage.TYPE_INT_RGB);
            Graphics graphics = target.createGraphics();
            graphics.drawImage(image, 0, 0, width/clip, height/clip, null);
            graphics.setColor(color);
            graphics.setFont(font);
            graphics.drawString(watermask, 100, 100);
            graphics.dispose();

            savePic(target,filename,picType,false);

            return filename + "." + picType;
        } catch (IOException e) {
            throw new ServiceException(e.getMessage());
        }

    }

    @Override
    public int insertFile(com.zznzzn.myweb.pojo.File file) {
        return fileMapper.insertFile(file);
    }

    @Override
    public int deleteFile(String fileid) {
        return fileMapper.deleteFile(fileid);
    }
}
